package hr.ctg.domain.model;

// Generated 2007.05.02 22:50:59 by Hibernate Tools 3.2.0.b9

import hr.ctg.SystemException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.validator.NotNull;
import org.jboss.seam.annotations.Name;
import org.joda.time.DateTime;

/**
 * Objekt generated by hbm2java
 */
@Entity
@Name("objekt")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "objekt")
@NamedQueries( {
		@NamedQuery(name = "Objekt.findByMjestoNaziv", query = "select o from Objekt o where o.mjesto.naziv = ?"),
		@NamedQuery(name = "Objekt.findByMjesto", query = "select o from Objekt o where o.mjesto = ?"),
		@NamedQuery(name = "Objekt.findLikeMjesto", query = "select o from Objekt o where o.mjesto.naziv like ?"),
		@NamedQuery(name = "Objekt.findByAutor", query = "select o from Objekt o where autor = ? order by o.idObjekta"),
		@NamedQuery(name = "Objekt.findCountByAutor", query = "select count(o) from Objekt o where autor = ?"),
		@NamedQuery(name = "Objekt.findOBDBSByIdObjekta", query = "select (select avg(ocjena) from DojamPosjetitelja dp where dp.objekt.idObjekta = o.idObjekta and  komentar is not null) as ocjena,(select count(*) from DojamPosjetitelja dp2 where dp2.objekt.idObjekta = o.idObjekta) as brojDojmova, (select count(s.idSlike) from Slika s where s.objekt.idObjekta=o.idObjekta) as brojSlika,(select sum(p.brojPosjeta) from Posjet p where p.objekt.idObjekta = o.idObjekta) as brojPosjeta from Objekt o where o.idObjekta = ?"),
		@NamedQuery(name = "Objekt.findOBDBSByIdObjektaList", query = "select (select avg(ocjena) from DojamPosjetitelja dp where dp.objekt.idObjekta = o.idObjekta and  komentar is not null) as ocjena,(select count(*) from DojamPosjetitelja dp2 where dp2.objekt.idObjekta = o.idObjekta) as brojDojmova, (select count(s.idSlike) from Slika s where s.objekt.idObjekta=o.idObjekta) as brojSlika from Objekt o where o.idObjekta in (?)"),
		@NamedQuery(name = "Objekt.getStatsByTipObjekta", query = "select o.tipObjekta.idTipaObjekta,COUNT(o.tipObjekta.idTipaObjekta) from Objekt o GROUP BY o.tipObjekta.idTipaObjekta"),
		@NamedQuery(name = "Objekt.findByOtokId", query = "select o from Objekt o join o.mjesto m where m.otok.idOtoka = ?"),
		@NamedQuery(name = "Objekt.findByOtok", query = "select o from Objekt o join o.mjesto m where m.otok = ?"),
		@NamedQuery(name = "Objekt.findByZupanijaId", query = "select o from Objekt o join o.mjesto m join m.zupanija z where z.idZupanje = ?"),
		@NamedQuery(name = "Objekt.findByZupanija", query = "select o from Objekt o join o.mjesto m join m.zupanija z where z = ?"),
		@NamedQuery(name = "Objekt.findByMjestoId", query = "select o from Objekt o where o.mjesto.idMjesta = ?"),
		@NamedQuery(name = "Objekt.findByPosta", query = "select o from Objekt o join o.mjesto m where m.posta = ?"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdTipaObjekta", query = "select o from Objekt o join o.mjesto m left join o.opisObjektas oo join o.tipObjekta to join o.dojamPosjetiteljas dpo where to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findByIdTipaObjekta", query = "select distinct o from Objekt o join o.tipObjekta to where to.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdTipaObjektaJezik", query = "select distinct o from Objekt o join o.tipObjekta to join o.opisObjektas oo join o.posjetObjektas p where to.idTipaObjekta = ? and oo.jezik.oznaka = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findByIdMjestaIdTipaObjekta", query = "select distinct o from Objekt o join o.tipObjekta to where o.mjesto.idMjesta = ? and to.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findByIdOtokaIdTipaObjekta", query = "select distinct o from Objekt o join o.tipObjekta to where o.mjesto.otok.idOtoka = ? and to.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findByIdZupanijeIdTipaObjekta", query = "select distinct o from Objekt o join o.tipObjekta to where o.mjesto.zupanija.idZupanje = ? and to.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findByLastDojam", query = "select o from Objekt o join o.dojamPosjetiteljas dpo order by dpo.datum desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdMjestaIdTipaObjekta", query = "select o from Objekt o join o.mjesto m join o.tipObjekta to join o.dojamPosjetiteljas dpo where m.idMjesta = ? and to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdZupanijeIdTipaObjekta", query = "select o from Objekt o join o.mjesto m join m.zupanija z join o.tipObjekta to join o.dojamPosjetiteljas dpo where to.idTipaObjekta = ? and z.idZupanje = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdMjesta", query = "select o from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.idMjesta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdOtoka", query = "select o from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.otok.idOtoka = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdZupanije", query = "select o from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.zupanija.idZupanje = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findTopByOcjenaIdOtokaIdTipaObjekta", query = "select o from Objekt o join o.mjesto m join m.otok ot join o.tipObjekta to join o.dojamPosjetiteljas dpo where ot.idOtoka = ? and to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Objekt.findByKorisnikSlike", query = "select distinct(o) from Objekt o join o.slikas s where s.korisnik = ?"),
		@NamedQuery(name = "Objekt.findByKorisnikDojmovi", query = "select distinct(o) from Objekt o join o.dojamPosjetiteljas d where d.korisnik = ?"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjekta", query = "select o from Objekt o join o.posjetObjektas p group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdMjesta", query = "select p.objekt from Posjet p  where p.objekt.mjesto.idMjesta = ? group by p.objekt order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopMAByPosjetObjektaIdMjesta", query = "select o from Objekt o join fetch o.mjesto m join fetch o.adresas a join o.posjetObjektas p where o.mjesto.idMjesta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdOtoka", query = "select o from Objekt o join o.mjesto m join o.posjetObjektas p where m.otok.idOtoka = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopMAByPosjetObjektaIdOtoka", query = "select o from Objekt o join fetch o.mjesto m join fetch o.adresas a join o.posjetObjektas p where m.otok.idOtoka = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdZupanije", query = "select o from Objekt o join o.mjesto m join o.posjetObjektas p where m.zupanija.idZupanje = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopMAByPosjetObjektaIdZupanije", query = "select o from Objekt o join fetch o.mjesto m join fetch o.adresas a join o.posjetObjektas p where m.zupanija.idZupanje = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaStartEndDate", query = "select o from Objekt o join o.posjetObjektas p where p.datumPosjete between ? and ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdMjestaIdTipaObjekta", query = "select o from Objekt o join o.posjetObjektas p where o.mjesto.idMjesta = ? and o.tipObjekta.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdZupanijeIdTipaObjekta", query = "select o from Objekt o join o.posjetObjektas p where o.tipObjekta.idTipaObjekta = ? and o.mjesto.zupanija.idZupanje = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdOtokaIdTipaObjekta", query = "select o from Objekt o join o.posjetObjektas p where o.mjesto.otok.idOtoka = ? and o.tipObjekta.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findTopByPosjetObjektaIdTipaObjekta", query = "select distinct o from Objekt o join o.tipObjekta to join o.posjetObjektas p where to.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Objekt.findCountByOcjenaBrojPosjetaIdMjesta", query = "select count(distinct o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo join o.posjetObjektas p where m.idMjesta = ? and (dpo.ocjena > 0 or p.brojPosjeta > 0)"),
		@NamedQuery(name = "Objekt.findCountByOcjenaBrojPosjetaIdOtoka", query = "select count(distinct o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo join o.posjetObjektas p where m.otok.idOtoka = ? and (dpo.ocjena > 0 or p.brojPosjeta > 0)"),
		@NamedQuery(name = "Objekt.findCountByOcjenaBrojPosjetaIdZupanije", query = "select count(distinct o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo join o.posjetObjektas p where m.zupanija.idZupanje = ? and (dpo.ocjena > 0 or p.brojPosjeta > 0)"),
		@NamedQuery(name = "Objekt.findCountByIdMjestaIdTipaObjekta", query = "select count(distinct o) from Objekt o where o.mjesto.idMjesta = ? and o.tipObjekta.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findCountByIdOtokaIdTipaObjekta", query = "select count(distinct o) from Objekt o where o.mjesto.otok.idOtoka = ? and o.tipObjekta.idTipaObjekta = ?"),
		@NamedQuery(name = "Objekt.findCountByIdZupanije", query = "select count(distinct o) from Objekt o where o.mjesto.zupanija.idZupanje = ?"),
		@NamedQuery(name = "Objekt.findCountByIdMjesta", query = "select count(distinct o) from Objekt o where o.mjesto.idMjesta = ?"),
		@NamedQuery(name = "Objekt.findCountByIdOtoka", query = "select count(distinct o) from Objekt o where o.mjesto.otok.idOtoka = ?"),
		@NamedQuery(name = "Objekt.findByIdObjektaIdMotritelja", query = "select o from Objekt o join o.motriteljs k where o.idObjekta = ? and k.idKorisnika = ?"),
		@NamedQuery(name = "Objekt.findCountTopByOcjena", query = "select count(o) from Objekt o join o.dojamPosjetiteljas dpo"),
		@NamedQuery(name = "Objekt.findCountTopByOcjenaIdZupanije", query = "select count(o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.zupanija.idZupanje = ?"),
		@NamedQuery(name = "Objekt.findCountTopByOcjenaIdMjesta", query = "select count(o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.idMjesta = ?"),
		@NamedQuery(name = "Objekt.findCountTopByOcjenaIdOtoka", query = "select count(o) from Objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.otok.idOtoka = ?"),
		@NamedQuery(name = "Objekt.findCountTopByPosjeti", query = "select count(o) from Objekt o join o.posjetObjektas p"),
		@NamedQuery(name = "Objekt.findCountTopByPosjetiIdZupanije", query = "select count(o) from Objekt o join o.mjesto m join o.posjetObjektas p where m.zupanija.idZupanje = ?"),
		@NamedQuery(name = "Objekt.findCountTopByPosjetiIdMjesta", query = "select count(o) from Objekt o join o.mjesto m join o.posjetObjektas p where m.idMjesta = ?"),
		@NamedQuery(name = "Objekt.findCountTopByPosjetiIdOtoka", query = "select count(o) from Objekt o join o.mjesto m join o.posjetObjektas p where m.otok.idOtoka= ?"),
		@NamedQuery(name = "Objekt.findByTOMLatLog", query = "select o from Objekt o where o.tipObjekta = ? and o.mjesto = ? and o.latituda is not null and o.longituda is not null"),
		@NamedQuery(name = "Objekt.findByIdTOLatLog", query = "select o from Objekt o where o.tipObjekta.idTipaObjekta = ? and o.latituda is not null and o.longituda is not null"),
		@NamedQuery(name = "Objekt.findAMPByIdTOLatLog", query = "select o from Objekt o join fetch o.adresas a join fetch a.mjesto m join fetch m.posta p where o.tipObjekta.idTipaObjekta = ? and o.latituda is not null and o.longituda is not null"),
		@NamedQuery(name = "Objekt.findATOById", query = "select o from Objekt o join fetch o.adresas a join fetch o.tipObjekta to where o.idObjekta = ?"),
		@NamedQuery(name = "Objekt.findByIdFAEATCOMTOOO", query = "select o from Objekt o left join fetch o.adresas a left join fetch o.emailAdresas ea left join fetch o.telefons t left join fetch o.cijenas c left join fetch o.osobinas os left join fetch o.mjesto m left join fetch o.tipObjekta to left join fetch o.opisObjektas oo where o.idObjekta = ?"),
		@NamedQuery(name = "Objekt.findByIdMotritelja", query = "select o from Objekt o join o.motriteljs m where m.idKorisnika = ?"),
		@NamedQuery(name = "Objekt.findByIdOglasivaca", query = "select o from Objekt o join o.oglasivac m where m.idKorisnika = ?"),
		@NamedQuery(name = "Objekt.findByIdAutora", query = "select o from Objekt o join o.autor m where m.idKorisnika = ?") })
public class Objekt implements Comparable<Objekt>, java.io.Serializable {
	private static final long serialVersionUID = 7475929947878666425L;
	private static final NumberFormat ctgIdNF = new DecimalFormat("00000");
	// private static final SimpleDateFormat date = new
	// SimpleDateFormat("dd.MM");
	// private static final SimpleDateFormat time = new
	// SimpleDateFormat("HH:mm");

	private Integer idObjekta;
	private TipObjekta tipObjekta;
	private Mjesto mjesto;
	private Korisnik autor;
	private Korisnik oglasivac;
	private Kategorija kategorija;
	private Smjestaj smjestaj;
	private String naziv;
	private String siteUrl;
	private Character status;
	private Double longituda;
	private Double latituda;
	private Integer zoom;
	private String interniId;
	private String ctgId;
	private Integer brojDojmova;
	private Integer brojPosjeta;
	private Double ocjena;
	private Integer brojSlika;
	private int idPocetneSlike;
	private Float minCijena;
	private Float maxCijena;
	private Date zadnjeAzuriranje;
	private Boolean istaknutaPonuda;

	private Set<Osobina> osobinas = new HashSet<Osobina>(0);
	private Set<Telefon> telefons = new HashSet<Telefon>(0);
	private Set<DnevnikAktivnosti> dnevnikAktivnostis = new HashSet<DnevnikAktivnosti>(
			0);
	private Set<Slika> slikas = new HashSet<Slika>(0);
	private Set<Adresa> adresas = new HashSet<Adresa>(0);
	private Set<DojamPosjetitelja> dojamPosjetiteljas = new HashSet<DojamPosjetitelja>(
			0);
	private Set<EmailAdresa> emailAdresas = new HashSet<EmailAdresa>(0);
	private Set<Opis> opisObjektas = new HashSet<Opis>(0);
	private Set<Posjet> posjetObjektas = new HashSet<Posjet>(0);
	private Set<Objava> objavas = new HashSet<Objava>(0);
	private Set<Cijena> cijenas = new HashSet<Cijena>(0);
	private Set<Korisnik> motriteljs = new HashSet<Korisnik>(0);

	public Objekt() {
	}

	public void setCTGID() {
		final DateTime dt = new DateTime(zadnjeAzuriranje.getTime());
		final int year = dt.getYear();
		final int month = dt.getMonthOfYear();
		switch (year) {
		case 2008:
			ctgId = "A";
			break;
		case 2009:
			ctgId = "B";
			break;
		case 2010:
			ctgId = "C";
			break;
		case 2011:
			ctgId = "D";
			break;
		case 2012:
			ctgId = "E";
			break;
		case 2013:
			ctgId = "F";
			break;
		case 2014:
			ctgId = "G";
			break;
		case 2015:
			ctgId = "H";
			break;
		default:
			throw new RuntimeException("Uspjeli smo! :) ");
		}

		switch (month) {
		case 1:
			ctgId += "A";
			break;
		case 2:
			ctgId += "A";
			break;
		case 3:
			ctgId += "A";
			break;
		case 4:
			ctgId += "A";
			break;
		case 5:
			ctgId += "A";
			break;
		case 6:
			ctgId += "A";
			break;
		case 7:
			ctgId += "A";
			break;
		case 8:
			ctgId += "A";
			break;
		case 9:
			ctgId += "A";
			break;
		case 10:
			ctgId += "A";
			break;
		case 11:
			ctgId += "A";
			break;
		case 12:
			ctgId += "A";
			break;
		}
		ctgId += ctgIdNF.format(idObjekta);
	}

	public Objekt(final Integer idObjekta) {
		this.idObjekta = idObjekta;
	}

	public Objekt(final int idObjekta, final TipObjekta tipObjekta,
			final Mjesto mjesto, final String naziv) {
		this.idObjekta = idObjekta;
		this.tipObjekta = tipObjekta;
		this.mjesto = mjesto;
		this.naziv = naziv;
	}

	public Objekt(final int idObjekta, final TipObjekta tipObjekta,
			final Mjesto mjesto, final String naziv, final String siteUrl,
			final Set<Osobina> osobinas, final Set<Telefon> telefons,
			final Set<DnevnikAktivnosti> dnevnikAktivnostis,
			final Set<Slika> slikas, final Set<Adresa> adresas,
			final Set<DojamPosjetitelja> dojamPosjetiteljas,
			final Set<EmailAdresa> emailAdresas) {
		this.idObjekta = idObjekta;
		this.tipObjekta = tipObjekta;
		this.mjesto = mjesto;
		this.naziv = naziv;
		this.siteUrl = siteUrl;
		this.osobinas = osobinas;
		this.telefons = telefons;
		this.dnevnikAktivnostis = dnevnikAktivnostis;
		this.slikas = slikas;
		this.adresas = adresas;
		this.dojamPosjetiteljas = dojamPosjetiteljas;
		this.emailAdresas = emailAdresas;
	}

	public static enum Status {
		NEW('N'), ACCEPTED('A'), DELETED('D');

		private Character mark;

		Status(final Character mark) {
			this.mark = mark;
		}

		public Character getMark() {
			return mark;
		}
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Adresa> getAdresas() {
		return adresas;
	}

	@Transient
	public Adresa getAdresa(final int idTipaAdrese) {
		if (adresas != null) {
			for (final Adresa adresa : adresas) {
				if (adresa.getTipAdrese().getIdTipaAdrese() == idTipaAdrese) {
					return adresa;
				}
			}
		}
		return null;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<DnevnikAktivnosti> getDnevnikAktivnostis() {
		return dnevnikAktivnostis;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<DojamPosjetitelja> getDojamPosjetiteljas() {
		return dojamPosjetiteljas;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<EmailAdresa> getEmailAdresas() {
		return emailAdresas;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Objava> getObjavas() {
		return objavas;
	}

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id_objekta", unique = true, nullable = false)
	public Integer getIdObjekta() {
		return idObjekta;
	}

	@Column(name = "latituda", nullable = true)
	public Double getLatituda() {
		return latituda;
	}

	@Column(name = "longituda", nullable = true)
	public Double getLongituda() {
		return longituda;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_mjesta", nullable = false)
	@NotNull
	public Mjesto getMjesto() {
		return mjesto;
	}

	@Column(name = "naziv", nullable = false)
	@NotNull
	public String getNaziv() {
		return naziv;
	}

	// @Column(name = "opis")

	public Opis getOpis(final String currentLanguage) {
		if (opisObjektas != null) {
			for (final Opis opisObjekta : opisObjektas) {
				if (opisObjekta.getJezik().getOznaka().equals(currentLanguage)) {
					return opisObjekta;
				}
			}
		}
		return null;
	}

	@Column(name = "site_url")
	public String getSiteUrl() {
		return siteUrl;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Slika> getSlikas() {
		return slikas;
	}

	@Column(name = "status", nullable = false)
	@NotNull
	public Character getStatus() {
		return status;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Telefon> getTelefons() {
		return telefons;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_tipa_objekta", nullable = false)
	@NotNull
	public TipObjekta getTipObjekta() {
		return tipObjekta;
	}

	@Column(name = "zoom", nullable = true)
	public Integer getZoom() {
		return zoom;
	}

	public void setAdresas(final Set<Adresa> adresas) {
		this.adresas = adresas;
	}

	public void setDnevnikAktivnostis(
			final Set<DnevnikAktivnosti> dnevnikAktivnostis) {
		this.dnevnikAktivnostis = dnevnikAktivnostis;
	}

	public void setDojamPosjetiteljas(
			final Set<DojamPosjetitelja> dojamPosjetiteljas) {
		this.dojamPosjetiteljas = dojamPosjetiteljas;
	}

	public void setEmailAdresas(final Set<EmailAdresa> emailAdresas) {
		this.emailAdresas = emailAdresas;
	}

	public void setIdObjekta(final Integer idObjekta) {
		this.idObjekta = idObjekta;
	}

	public void setLatituda(final Double latituda) {
		this.latituda = latituda;
	}

	public void setLongituda(final Double longituda) {
		this.longituda = longituda;
	}

	public void setMjesto(final Mjesto mjesto) {
		this.mjesto = mjesto;
	}

	public void setNaziv(final String naziv) {
		this.naziv = naziv;
	}

	public void setSiteUrl(final String siteUrl) {
		this.siteUrl = siteUrl;
	}

	public void setSlikas(final Set<Slika> slikas) {
		this.slikas = slikas;
	}

	public void setStatus(final Character status) {
		this.status = status;
	}

	public void setTelefons(final Set<Telefon> telefons) {
		this.telefons = telefons;
	}

	public void setTipObjekta(final TipObjekta tipObjekta) {
		this.tipObjekta = tipObjekta;
	}

	public void setZoom(final Integer zoom) {
		this.zoom = zoom;
	}

	@Transient
	public int getIdPocetneSlike() {
		return idPocetneSlike;
	}

	public void setIdPocetneSlike(final int idPocetneSlike) {
		this.idPocetneSlike = idPocetneSlike;
	}

	@Override
	public String toString() {
		return naziv;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_autora", nullable = false)
	@NotNull
	public Korisnik getAutor() {
		return autor;
	}

	public void setAutor(final Korisnik autor) {
		this.autor = autor;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Opis> getOpisObjektas() {
		return opisObjektas;
	}

	public void setOpisObjektas(final Set<Opis> opisObjektas) {
		this.opisObjektas = opisObjektas;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	// @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy =
	// "objekts")
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "osobina_objekta", joinColumns = @JoinColumn(name = "id_objekta", referencedColumnName = "id_objekta"), inverseJoinColumns = @JoinColumn(name = "id_osobine", referencedColumnName = "id_osobine"))
	public Set<Osobina> getOsobinas() {
		return osobinas;
	}

	public void setOsobinas(final Set<Osobina> osobinas) {
		this.osobinas = osobinas;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		return ((Objekt) obj).getIdObjekta() == idObjekta;
	}

	public int compareTo(final Objekt o) {
		if (o.getIdObjekta() < idObjekta) {
			return -1;
		} else if (o.getIdObjekta() > idObjekta) {
			return 1;
		} else {
			return 0;
		}
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Posjet> getPosjetObjektas() {
		return posjetObjektas;
	}

	public void setPosjetObjektas(final Set<Posjet> posjetObjektas) {
		this.posjetObjektas = posjetObjektas;
	}

	// @Formula("(select count(dp2.id_dpp) from dojam_posjetitelja dp2 where dp2.id_objekta = id_objekta)")
	@Transient
	public Integer getBrojDojmova() {
		return brojDojmova;
	}

	public void setBrojDojmova(final Integer brojDojmova) {
		this.brojDojmova = brojDojmova;
	}

	// @Formula("(select avg(dp.ocjena) from dojam_posjetitelja dp where dp.id_objekta = id_objekta)")
	@Transient
	public Double getOcjena() {
		return ocjena;
	}

	public void setOcjena(final Double ocjena) {
		this.ocjena = ocjena;
	}

	// @Formula("(select count(s.id_slike) from slika s where s.id_objekta=id_objekta)")
	@Transient
	public Integer getBrojSlika() {
		return brojSlika;
	}

	public void setBrojSlika(final Integer brojSlika) {
		this.brojSlika = brojSlika;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_kategorije", nullable = true)
	public Kategorija getKategorija() {
		return kategorija;
	}

	public void setKategorija(final Kategorija kategorija) {
		this.kategorija = kategorija;
	}

	public void setObjavas(final Set<Objava> objavas) {
		this.objavas = objavas;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "objekt")
	public Set<Cijena> getCijenas() {
		return cijenas;
	}

	public void setCijenas(final Set<Cijena> cijenas) {
		this.cijenas = cijenas;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	// @OneToOne(mappedBy = "objekt", cascade = CascadeType.ALL, fetch =
	// FetchType.LAZY, optional = true, targetEntity = Smjestaj.class)
	// @PrimaryKeyJoinColumn(name = "id_objekta", referencedColumnName =
	// "id_objekta")
	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "id_smjestaja", referencedColumnName = "id_objekta", nullable = true, unique = true)
	public Smjestaj getSmjestaj() {
		return smjestaj;
	}

	public void setSmjestaj(final Smjestaj smjestaj) {
		this.smjestaj = smjestaj;
		if (smjestaj != null) {
			smjestaj.setIdObjekta(idObjekta);
		}
	}

	@Column(name = "interni_id")
	public String getInterniId() {
		return interniId;
	}

	public void setInterniId(final String interniId) {
		this.interniId = interniId;
	}

	@Column(name = "ctg_id")
	public String getCtgId() {
		return ctgId;
	}

	public void setCtgId(final String ctgId) {
		this.ctgId = ctgId;
	}

	@SuppressWarnings("unchecked")
	public List<Osobina> getOsobine(final int count) {
		if (osobinas != null) {
			final List<Osobina> s = new ArrayList<Osobina>();
			if (osobinas.size() > count) {
				int i = 0;
				for (final Osobina o : osobinas) {
					s.add(o);
					if (++i == count) {
						break;
					}
				}
				return s;
			} else {
				return new ArrayList<Osobina>(osobinas);
			}
		}
		return Collections.EMPTY_LIST;
	}

	public List<String> getSmjestaj(final int count,
			final Map<String, String> messages) {
		if (smjestaj != null) {
			final Method[] mth = smjestaj.getClass().getMethods();
			List<String> smj = new ArrayList<String>();
			for (int i = 0; i < mth.length; i++) {
				final Method method = mth[i];
				if (method.getName().startsWith("get")
						&& !method.getName().startsWith("getIdObjekta")
						&& !method.getName().startsWith("getObjekt")
						&& !method.getName().startsWith("getClass")
						&& !method.getName().startsWith(
								"getHibernateLazyInitializer")
						&& !method.getName().endsWith("Minute")
						&& !method.getName().endsWith("Sat")) {
					Object result = null;
					try {
						result = method.invoke(smjestaj);
					} catch (final IllegalArgumentException e) {
						throw new SystemException(e.getMessage(), e);
					} catch (final IllegalAccessException e) {
						throw new SystemException(e.getMessage(), e);
					} catch (final InvocationTargetException e) {
						throw new SystemException(e.getMessage(), e);
					}

					if (result != null) {
						String key = method.getName().substring(3,
								method.getName().length());
						key = "label.osobina."
								+ Character.toLowerCase(key.charAt(0))
								+ key.substring(1, key.length());
						try {
							smj.add(MessageFormat.format(messages.get(key),
									result));
						} catch (java.lang.IllegalArgumentException e) {
						}
					}
				}
			}

			if (smj.size() > count) {
				smj = smj.subList(0, count);
			}
			return smj;
		}
		return Collections.emptyList();
	}

	@Transient
	public Float getMinCijena() {
		if (minCijena == null) {
			minCijena = getCijena(true);
		}
		return minCijena;
	}

	@Transient
	public Float getMaxCijena() {
		if (maxCijena == null) {
			maxCijena = getCijena(false);
		}
		return maxCijena;
	}

	private Float getCijena(final boolean min) {
		if (cijenas != null && cijenas.size() > 0) {
			final Comparator<Cijena> c;
			if (tipObjekta.getIdTipaObjekta() == 4) {
				c = new Comparator<Cijena>() {
					@Override
					public int compare(final Cijena o1, final Cijena o2) {
						if (min) {
							final float o1c = o1.getJednokrevetna() == null ? 0
									: o1.getJednokrevetna();
							final float o2c = o2.getJednokrevetna() == null ? 0
									: o2.getJednokrevetna();

							return o2c < o1c ? 1 : o2c > o1c ? -1 : 0;
						} else {
							final float o1c = o1.getApartman() == null ? 0 : o1
									.getApartman();
							final float o2c = o2.getApartman() == null ? 0 : o2
									.getApartman();

							return o2c > o1c ? 1 : o2c < o1c ? -1 : 0;
						}
					}
				};
			} else {
				c = new Comparator<Cijena>() {
					@Override
					public int compare(final Cijena o1, final Cijena o2) {
						final float o1c = o1.getDan() == null ? 0 : o1.getDan();
						final float o2c = o2.getDan() == null ? 0 : o2.getDan();
						if (min) {
							return o2c < o1c ? 1 : o2c > o1c ? -1 : 0;
						} else {
							return o2.getDan() > o1.getDan() ? 1
									: o2c < o1c ? -1 : 0;
						}
					}

				};
			}
			final List<Cijena> l = new ArrayList<Cijena>();
			for (final Cijena cijena : cijenas) {
				if (tipObjekta.getIdTipaObjekta() == 4) {
					if (min) {
						if (cijena.getJednokrevetna() != null) {
							l.add(cijena);
						}
					} else {
						if (cijena.getApartman() != null) {
							l.add(cijena);
						}
					}
				} else {
					if (cijena.getDan() != null) {
						l.add(cijena);
					}
				}
			}
			Collections.sort(l, c);
			if (l.size() > 0) {
				if (tipObjekta.getIdTipaObjekta() == 4) {
					if (min) {
						return l.get(0).getJednokrevetna();
					} else {
						return l.get(0).getApartman();
					}
				} else {
					return l.get(0).getDan();
				}
			}
		}
		return null;
	}

	@Column(name = "zadnje_azuriranje")
	public Date getZadnjeAzuriranje() {
		return zadnjeAzuriranje;
	}

	public void setZadnjeAzuriranje(final Date zadnjeAzuriranje) {
		this.zadnjeAzuriranje = zadnjeAzuriranje;
	}

	@SuppressWarnings("unused")
	@PreUpdate
	@PrePersist
	private void preAction() {
		setZadnjeAzuriranje(new Date());
	}

	@Column(name = "istaknuta_ponuda")
	public Boolean getIstaknutaPonuda() {
		return istaknutaPonuda;
	}

	public void setIstaknutaPonuda(final Boolean istaknutaPonuda) {
		this.istaknutaPonuda = istaknutaPonuda;
	}

	// @Formula("(select sum(brojPosjeta) from posjet po3 where po3.id_objekta = id_objekta)")
	@Transient
	public Integer getBrojPosjeta() {
		return brojPosjeta;
	}

	public void setBrojPosjeta(final Integer brojPosjeta) {
		this.brojPosjeta = brojPosjeta;
	}

	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_oglasivaca", nullable = true)
	public Korisnik getOglasivac() {
		return oglasivac;
	}

	public void setOglasivac(final Korisnik oglasivac) {
		this.oglasivac = oglasivac;
	}

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "favorit", joinColumns = @JoinColumn(name = "id_objekta", referencedColumnName = "id_objekta"), inverseJoinColumns = @JoinColumn(name = "id_korisnika", referencedColumnName = "id_korisnika"))
	public Set<Korisnik> getMotriteljs() {
		return motriteljs;
	}

	public void setMotriteljs(final Set<Korisnik> motriteljs) {
		this.motriteljs = motriteljs;
	}
}
